//package com.ruoyi.system.condig;
//
//import com.ruoyi.system.domain.vo.SqlOperationLog;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.mapping.ParameterMapping;
//import org.apache.ibatis.mapping.SqlCommandType;
//import org.apache.ibatis.plugin.*;
//import org.apache.ibatis.reflection.MetaObject;
//import org.apache.ibatis.session.Configuration;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.apache.ibatis.type.TypeHandlerRegistry;
//import org.springframework.stereotype.Component;
//
//import java.time.LocalDateTime;
//import java.util.List;
//import java.util.Properties;
//
///**
// * MyBatis 全局 SQL 拦截器，记录所有 SQL 操作
// */
//@Component
//@Intercepts({
//        // 拦截查询操作
//        @Signature(type = Executor.class, method = "query",
//                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
//        // 拦截增删改操作
//        @Signature(type = Executor.class, method = "update",
//                args = {MappedStatement.class, Object.class})
//})
//public class SqlOperationInterceptor implements Interceptor {
//
//    // 从配置文件读取开关（默认关闭）
//    //@Value("${mybatis.sql.log.enabled:false}")
//    private boolean logEnabled = true;
//
//    // SQL 最大长度限制（避免日志过长）
//    //@Value("${mybatis.sql.log.max-length:2000}")
//    private int sqlMaxLength = 50000;
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        // 关闭日志时直接执行原方法
//        if (!logEnabled) {
//            return invocation.proceed();
//        }
//
//        // 1. 获取拦截参数
//        Object[] args = invocation.getArgs();
//        MappedStatement ms = (MappedStatement) args[0];
//        Object parameter = args[1];
//        Configuration configuration = ms.getConfiguration();
//
//        // 2. 初始化日志对象
//        SqlOperationLog log = new SqlOperationLog();
//        log.setExecuteDateTime(LocalDateTime.now());
//        log.setOperationType(getOperationType(ms.getSqlCommandType()));
//
//        // 3. 解析 SQL 和参数
//        BoundSql boundSql = ms.getBoundSql(parameter);
//        log.setParameters(extractParameters(boundSql, configuration)); // 提取参数
//        log.setSql(formatSql(boundSql.getSql(), boundSql, configuration)); // 格式化 SQL（替换占位符）
//
//        // 4. 执行 SQL 并记录耗时
//        long startTime = System.currentTimeMillis();
//        Object result;
//        try {
//            result = invocation.proceed(); // 执行原 SQL 操作
//            log.setResult("SUCCESS");
//        } catch (Exception e) {
//            log.setResult("FAILURE");
//            log.setErrorMessage(e.getMessage());
//            throw e; // 继续抛出异常，不影响业务
//        } finally {
//            log.setExecuteTimeMs(System.currentTimeMillis() - startTime);
//            printSqlLog(log); // 打印日志
//        }
//
//        return result;
//    }
//
//    /**
//     * 转换操作类型（SqlCommandType 转字符串）
//     */
//    private String getOperationType(SqlCommandType commandType) {
//        switch (commandType) {
//            case SELECT: return "SELECT";
//            case INSERT: return "INSERT";
//            case UPDATE: return "UPDATE";
//            case DELETE: return "DELETE";
//            default: return "UNKNOWN";
//        }
//    }
//
//    /**
//     * 提取 SQL 参数值
//     */
//    private Object[] extractParameters(BoundSql boundSql, Configuration configuration) {
//        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//        Object parameterObject = boundSql.getParameterObject();
//        Object[] parameters = new Object[parameterMappings.size()];
//
//        if (parameterObject != null) {
//            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
//            MetaObject metaObject = configuration.newMetaObject(parameterObject);
//            for (int i = 0; i < parameterMappings.size(); i++) {
//                ParameterMapping pm = parameterMappings.get(i);
//                //if (pm.getMode() != ParameterMapping.Mode.OUT) {
//                //    String propertyName = pm.getProperty();
//                //    parameters[i] = metaObject.getValue(propertyName);
//                //}
//            }
//        }
//        return parameters;
//    }
//
//    /**
//     * 格式化 SQL（替换 ? 占位符为实际参数）
//     */
//    private String formatSql(String sql, BoundSql boundSql, Configuration configuration) {
//        // 去除 SQL 中的换行和多余空格
//        sql = sql.replaceAll("[\n\r\t]", " ").replaceAll(" +", " ");
//
//        // 替换 ? 占位符为实际参数
//        Object parameterObject = boundSql.getParameterObject();
//        if (parameterObject == null) {
//            return limitSqlLength(sql);
//        }
//
//        MetaObject metaObject = configuration.newMetaObject(parameterObject);
//        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//        for (ParameterMapping pm : parameterMappings) {
//            String propertyName = pm.getProperty();
//            if (metaObject.hasGetter(propertyName)) {
//                Object value = metaObject.getValue(propertyName);
//                String valueStr = formatParameterValue(value);
//                sql = sql.replaceFirst("\\?", valueStr);
//            }
//        }
//        return limitSqlLength(sql);
//    }
//
//    /**
//     * 格式化参数值（处理字符串、日期等特殊类型）
//     */
//    private String formatParameterValue(Object value) {
//        if (value == null) {
//            return "NULL";
//        }
//        if (value instanceof String || value instanceof Character) {
//            return "'" + value.toString().replace("'", "''") + "'"; // 转义单引号
//        }
//        if (value instanceof java.util.Date) {
//            return "'" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value) + "'";
//        }
//        return value.toString();
//    }
//
//    /**
//     * 限制 SQL 长度（避免日志过长）
//     */
//    private String limitSqlLength(String sql) {
//        if (sql.length() <= sqlMaxLength) {
//            return sql;
//        }
//        return sql.substring(0, sqlMaxLength) + "...";
//    }
//
//    /**
//     * 打印 SQL 日志到控制台（可扩展为写入文件/数据库）
//     */
//    private void printSqlLog(SqlOperationLog log) {
//        StringBuilder sb = new StringBuilder();
//        sb.append("\n===== MyBatis SQL 操作日志 =====")
//          .append("\n时间：").append(log.getExecuteDateTime())
//          .append("\n类型：").append(log.getOperationType())
//          .append("\nSQL：").append(log.getSql())
//          .append("\n参数：").append(arrayToString(log.getParameters()))
//          .append("\n耗时：").append(log.getExecuteTimeMs()).append("ms")
//          .append("\n结果：").append(log.getResult());
//        if (log.getErrorMessage() != null) {
//            sb.append("\n错误：").append(log.getErrorMessage());
//        }
//        sb.append("\n===============================\n");
//        System.out.println(sb.toString());
//    }
//
//    /**
//     * 数组转字符串（便于日志展示）
//     */
//    private String arrayToString(Object[] array) {
//        if (array == null || array.length == 0) {
//            return "[]";
//        }
//        StringBuilder sb = new StringBuilder("[");
//        for (Object obj : array) {
//            sb.append(obj).append(", ");
//        }
//        sb.setLength(sb.length() - 2);
//        sb.append("]");
//        return sb.toString();
//    }
//
//    @Override
//    public Object plugin(Object target) {
//        // 只对 Executor 接口生成代理
//        if (target instanceof Executor) {
//            return Plugin.wrap(target, this);
//        }
//        return target;
//    }
//
//    @Override
//    public void setProperties(Properties properties) {
//        // 支持通过 MyBatis 配置文件传递参数（可选）
//    }
//}